<?
    /* -*- Mode: PHP5; tab-width: 4; indent-tabs-mode: nil; basic-offset: 4 -*- */

    /*********************************************************
    *            --== InArch ==--
    *
    * Ajax Abstraction Layer
    *
    * @author Kulikov Alexey <a.kulikov@gmail.com>
    * @version n/a
    * @since 23.04.2005
    * @copyright essentialmind.com 2005
    *
    *********************************************************/

    /***
    * Abstract Class ajaxAction
    ****
    * This is a signature class for all the possible ajax
    * actions that can take place in the admin panel.
    * Children of this class are initiated from adminAjax.class.php
    ****
    * @package ajax
    * @author A Kulikov <a.kulikov@gmail.com>
    * @version n/a
    * @since 23.04.2005
    * @copyright essentialmind.com 2005
    ***/
    abstract class ajaxAction{

        /**
         * reference to the ADODB Connection
         *
         * @var ADOConnection
         */
        protected $db;
        protected $smarty;  //reference to smarty
        protected $log;     //reference to event logger

        /**
         * Enter description here...
         *
         * @var AjaxResponseWddx
         */
        protected $r;       //reference to an internal ajax handler


        /**
         * Constructor
         *
         * @param ADOConnection $db
         * @param mySmarty $smarty
         * @param object $log
         */
        function __construct(ADOConnection $db,mySmarty $smarty,$log){
            $this->db       = $db;
            $this->smarty   = $smarty;
            $this->log      = $log;
            $this->r        = new AjaxResponseJSON;
        }
        
        /**
         * Decode AJAX requests into valid UTF8 charachters
         *
         * @param unknown_type $str
         * @return unknown
         */
        public function unescape($str) {
            return encodingHandler::unescape($str);
        }
        
        abstract public function process();
    }


    abstract class AjaxResponse implements IteratorAggregate{
    	protected $result;
    	private $errorLabel;
        protected $forceXML = false;
        
    	function __construct(){
    		$this->clear();

    		$this->errorLabel = sha1(microtime());
    		ini_set('error_prepend_string', $this->errorLabel.ini_get('error_prepend_string'));
    		ini_set('error_append_string', ini_get('error_append_string').$this->errorLabel);

    		ob_start(array($this, "ob_handler"));
    	}


    	function clear(){
    		$this->result = array();
    	}


    	function ob_handler($buf){
    		if(!empty($buf)){
    			$regexp = '~'.$this->errorLabel.'(.*?)'.$this->errorLabel.'~msi';
    			if(preg_match_all($regexp, $buf, $mtch)){
    				$errors = array();
    				foreach($mtch[1] as $error) $errors[] = trim(strip_tags($error));
    				$this->result['_ERROR'] = implode("\n\n", $errors);
    				$buf = str_replace($this->errorLabel, '', $buf);
    			}

    			$this->result['_OUTPUT'] = $buf;
    		}
            
            if(!$this->forceXML){
                list($result, $headers) = $this->serializeResult();
    
                foreach($headers as $name => $content) header("$name: $content");
                return $result;
    		}else{
    		    header("Content-type: text/xml");
    		    header("Charset: utf-8");
    		    return $this->result['_OUTPUT'];
    		}
    	}

    	abstract protected function serializeResult();


    	function getIterator() { return new ArrayIterator($this->result); }
    	function __get($name) { return $this->result[$name]; }
    	function __set($name, $value) { $this->result[$name] = $value; }
    	function push($value) { $this->result[] = $value; }
    	
    	function forceXML() { $this->forceXML = true; }
    }


    class AjaxResponseJSON extends AjaxResponse{
    	protected function serializeResult(){    	    
    	    $text = json_encode($this->result);
    	    return array(
    			$text,
    			array(
    				"Content-type"		=> "application/json",
    				"charset"		    => "utf-8",
    				"Content-length"	=> strlen($text),
    			)
    		);
    	}        
    }
